package com.duoec.magichour.core.web.freemarker.model;

import com.duoec.magichour.core.utils.FileCacheUtils;
import com.duoec.magichour.core.utils.MD5Utils;
import com.duoec.magichour.core.web.freemarker.dto.FileSortedData;
import com.duoec.magichour.core.web.freemarker.dto.SortedData;
import com.duoec.magichour.core.web.freemarker.dto.StringSortedData;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import freemarker.template.TemplateException;

import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * Created by ycoe on 16/5/18.
 */
public class SortedVar implements BaseTemplateModel {

    private Map<String, SortedData> orderedDataMap = Maps.newConcurrentMap();

    /**
     * 数据列表
     */
    private List<SortedData> orderedDatas = Lists.newArrayList();

    /**
     * 最后修改时间
     */
    private long lastModified = 0;

    /**
     * 添加资源
     *
     * @param file 文本资源文件
     * @param sort 排序，越小越前
     */
    public void add(File file, Integer sort) {
        if (!file.exists()) {
            return;
        }

        long fileLastModified = file.lastModified();
        String key = MD5Utils.md5(file.getAbsolutePath()); //计算一个key

        SortedData sortedData = orderedDataMap.get(key);
        if (sortedData != null) {
            resetDataSort(sort, sortedData);
            return;
        }

        sortedData = new FileSortedData(file, sort == null ? getNextOrder() : sort, fileLastModified);
        addSortedData(key, sortedData, fileLastModified);
        FileCacheUtils.set(key, file);
    }

    /**
     * 添加内容
     *
     * @param content      内容
     * @param sort         排序,越小越前，为空时，自动排在后面
     * @param lastModified 最后修改时间
     */
    public void add(String content, Integer sort, long lastModified) {
        if (Strings.isNullOrEmpty(content)) {
            return;
        }

        String key = MD5Utils.md5(content); //计算一个key
        SortedData sortedData = orderedDataMap.get(key);
        if (sortedData != null) {
            resetDataSort(sort, sortedData);
            return;
        }

        sortedData = new StringSortedData(content, sort == null ? getNextOrder() : sort, lastModified);
        addSortedData(key, sortedData, lastModified);
    }

    @Override
    public void render(Writer out) throws TemplateException, IOException {
        if (orderedDatas != null) {
            Collections.sort(orderedDatas); //重新排序
            for (SortedData data : orderedDatas) {
                out.write(data.toString());
            }
        }
    }

    private void resetDataSort(Integer sort, SortedData sortedData) {
        if (sort != null && sortedData.getSort() > sort) {
            //尽量往前排
            sortedData.setSort(sort);
        }
    }

    private void addSortedData(String key, SortedData sortedData, long lastModified) {
        orderedDatas.add(sortedData);
        orderedDataMap.put(key, sortedData);
        this.lastModified = Math.max(lastModified, this.lastModified);
    }

    /**
     * 获取下一个顺序
     *
     * @return
     */
    private int getNextOrder() {
        int maxOrder = 0;
        for (SortedData item : orderedDatas) {
            maxOrder = Math.max(maxOrder, item.getSort());
        }
        return maxOrder + 10;
    }

    public long getLastModified() {
        return lastModified;
    }
}
